package edu.cs.usask.ca.silver.api.businesslogic;

import java.sql.SQLDataException;
import java.util.Date;

import edu.cs.usask.ca.silver.api.persistence.StorageI;
import edu.cs.usask.ca.silver.businesslogic.ids.GroupID;
import edu.cs.usask.ca.silver.businesslogic.ids.UserID;

/**
 * This programming interface defines all features available with users. All
 * methods should be implemented with atomic database routines. each methods may
 * contain one or more 'transactional' actions. Roll-back strategy should also
 * apply at this level.
 * 
 * @author Yudi Xue
 * 
 */
public interface UserI {

	/**
	 * Create a new user with the specified information; a new user always have
	 * a new private group. When a private group is assigned, the private group
	 * id for this user is immutable thereafter.
	 * 
	 * @param uFirstName
	 *            first name of the user
	 * @param uLastName
	 *            last name of the user
	 * @param uEmail
	 *            user email
	 * @param uPasswd
	 *            user password
	 * @param storage TODO
	 * @return a unique user id
	 */
	public UserID createUser(String uFirstName, String uLastName,
			String uEmail, String uPasswd, StorageI storage) throws SQLDataException, Exception;

	/**
	 * Get all user ids
	 * @param storage TODO
	 * 
	 * @return a collection of all user ids
	 */
	public UserID[] getAllUserIds(StorageI storage) throws Exception;

	/**
	 * Get current user name
	 * 
	 * @param userID
	 *            a unique
	 * @param storage TODO
	 * @return user first name
	 */
	public String getFirstName(UserID userID, StorageI storage) throws Exception;

	/**
	 * get current user last name
	 * 
	 * @param userID
	 *            a unique user id
	 * @param storage TODO
	 * @return the user last name
	 */
	public String getLastName(UserID userID, StorageI storage) throws Exception;

	/**
	 * get current user email
	 * 
	 * @param userID
	 *            the unique user id
	 * @param storage TODO
	 * @return the user email
	 */
	public String getEmail(UserID userID, StorageI storage) throws Exception;

	/**
	 * get current user private group id
	 * 
	 * @param userID
	 *            the unique user id
	 * @param storage TODO
	 * @return the unique group id that represents the user's private group
	 */
	public GroupID getPrivateGroupID(UserID userID, StorageI storage) throws Exception;

	/**
	 * Get user id from the combination of user email and user password.
	 * 
	 * @param uEmail
	 *            the user email
	 * @param uPasswd
	 *            the user password
	 * @param storage TODO
	 * @return the unique user id
	 * 
	 */
	public UserID getUserIDFromEmailAndPassCombination(String uEmail,
			String uPasswd, StorageI storage) throws Exception;

	/**
	 * Verify current user password
	 * 
	 * @param uEmail
	 *            unique user id
	 * @param uPass
	 *            password
	 * @param storage TODO
	 * @return whether the user password has been verified
	 */
	public boolean verifyPassWord(String uEmail, String uPass, StorageI storage) throws Exception;

	/**
	 * Get the user registration date
	 * 
	 * @param userID
	 *            the unique user id
	 * @param storage TODO
	 * @return the date object including user registration date.
	 */
	public Date getRegistrationDate(UserID userID, StorageI storage) throws Exception;

	/**
	 * Get the specific user registration time
	 * 
	 * @param userID
	 *            the unique user id
	 * @param storage TODO
	 * @return the date object including user registration time.
	 * @throws Exception
	 */
	public Date getUserRegistrationTime(UserID userID, StorageI storage) throws Exception;

	/**
	 * Get the list of group IDs of all groups user has participated in.
	 * 
	 * @param userID
	 *            The unique integer ID of the user
	 * @param storage TODO
	 * @return An ArrayList<Integers> containing all group ids
	 */
	public GroupID[] getParticipatedGroupIds(UserID userID, StorageI storage) throws Exception;

	/**
	 * Get the basic information of a user.
	 * 
	 * @param userID
	 * @param storage TODO
	 * @return String[] an array containing identity, firstname, lastname, email
	 *         and password.
	 * 
	 */
	public String[] getBasicInfo(UserID userID, StorageI storage) throws Exception;

	/**
	 * Set the user's first name
	 * 
	 * @param userID
	 *            the unique user id
	 * @param updatedFirstName
	 *            new first name
	 * @param storage TODO
	 * @return whether the action succeeded
	 */
	public boolean setFirstName(UserID userID, String updatedFirstName, StorageI storage)
			throws Exception;

	/**
	 * Set the user's last name
	 * 
	 * @param userID
	 *            the unique user id
	 * @param updatedLastName
	 *            new last name
	 * @param storage TODO
	 * @return whether the action succeeded
	 */
	public boolean setLastName(UserID userID, String updatedLastName, StorageI storage)
			throws Exception;

	/**
	 * Update the user Email.
	 * 
	 * @param userID
	 * @param updatedEmail
	 * @param storage TODO
	 * @return whether the action succeeded
	 */
	public boolean setEmail(UserID userID, String updatedEmail, StorageI storage)
			throws Exception;

	/**
	 * Update user password. Such routine should take precaution to preclude
	 * from modifying other users' passwords.
	 * 
	 * @param userID
	 * @param updatedPasswd
	 *            new password
	 * @param storage TODO
	 * @return whether the action succeeded
	 */
	public boolean setPasswd(UserID userID, String updatedPasswd, StorageI storage)
			throws Exception;

	/**
	 * remove specified user
	 * 
	 * @param userID
	 *            the unique user id
	 * @param storage TODO
	 * @return whether the action succeeded
	 */
	public boolean deleteUser(UserID userID, StorageI storage) throws Exception;
}
